package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.comment.dto.CommentRepayDto;
import com.heima.comment.dto.CommentRepayLikeDto;
import com.heima.comment.dto.CommentRepaySaveDto;
import com.heima.comment.entity.ApComment;
import com.heima.comment.entity.ApCommentRepay;
import com.heima.comment.entity.ApCommentRepayLike;
import com.heima.comment.entity.ApUser;
import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.ICommentRepayService;
import com.heima.comment.vo.ApCommentRepayVo;
import com.heima.comment.vo.ApCommentVo;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.UserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class CommentRepayServiceImpl implements ICommentRepayService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private GreenTextScan greenTextScan;

    /**
     * 评论-保存
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveRepay(CommentRepaySaveDto dto) {

        // 参数判断
        if (dto==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 用户判断
        User user = UserThreadLocalUtil.get();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 添加：判断评论内容字数是否大于140字
        if (dto.getContent().length()>140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 阿里云文本审核
        boolean isPass = true;
        isPass = checkText(dto.getContent());
        if (!isPass) return ResponseResult.errorResult(404,"评论含有敏感词，请重新编辑！");

        // MongoDB保存
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        // apCommentRepay.setId("");
        if (user.getUserId()==0) {
            apCommentRepay.setUserId(user.getUserId());
            apCommentRepay.setUserName("游客");
        }else {
            ResponseResult<ApUser> responseResult = userFeign.getUserById(user.getUserId());
            if (responseResult!=null) {
                ApUser apUser = responseResult.getData();
                apCommentRepay.setUserId(user.getUserId());
                apCommentRepay.setUserName(apUser.getName());
            }
        }
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        // 新增
        mongoTemplate.save(apCommentRepay);

        // 差异：评论表的回复数量+1，参考文章点赞时情况
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(dto.getCommentId()));
        Update update = new Update();
        update.inc("repay");
        mongoTemplate.updateFirst(query,update,ApComment.class);

        return ResponseResult.okResult();
    }

    /**
     * aliyun自动审核文本
     * @param content
     * @return
     */
    private boolean checkText(String content) {
        boolean isPass = false;
        try {
            Map map = greenTextScan.greenTextScan(content);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                // suggestion
                // pass：文本正常，可以直接放行。
                // review：文本需要进一步人工审核。             label=porn
                // block：文本违规，可以直接删除或者限制公开。  label=porn
                case "pass":
                    isPass = true;
                    break;
                case "review":
                    log.info("[阿里云文本审核未通过，需要人工审核，原因是：{}]",map.get("label"));
                    isPass = false;
                    break;
                case "block":
                    log.info("[阿里云文本审核未通过，需要人工审核，原因是：{}]",map.get("label"));
                    isPass = false;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isPass;
    }

    /**
     * 评论-列表展示
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayDto dto) {
        if (dto==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        User user = UserThreadLocalUtil.get();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto.getSize()==null||dto.getSize()<=0||dto.getSize()>=50) {
            dto.setSize(10);
        }
        // 条件构造器
        Query query = new Query();
        query.addCriteria(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()));
        // 分页与排序
        Pageable pageable = PageRequest.of(0,dto.getSize(),Sort.Direction.DESC,"createdTime");
        query.with(pageable);
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);

        // 避免评论点赞重复
        List<ApCommentRepayVo> apCommentRepayVoList = new ArrayList<>();
        for (ApCommentRepay apCommentRepay : apCommentRepays) {
            ApCommentRepayVo apCommentRepayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay,apCommentRepayVo);
            Boolean hasKey = redisTemplate.hasKey("comment_repay_like_" + user.getUserId() + "_" + apCommentRepay.getId());
            apCommentRepayVo.setOperation(hasKey?0:1);
            apCommentRepayVoList.add(apCommentRepayVo);
        }

        return ResponseResult.okResult(apCommentRepayVoList);
    }

    /**
     * 评论-点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        // 判断
        if (dto==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        User user = UserThreadLocalUtil.get();
        if (user==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        // 思路：1.记录点赞数据；2.修改点赞数
        // 方案一：增删，不全部记录
        if (dto.getOperation()==0) {
            // 保存点赞数据
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            // apCommentRepayLike.setId("");
            apCommentRepayLike.setUserId(user.getUserId());
            apCommentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            apCommentRepayLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentRepayLike);
            // 修改记录数
            Query query = new Query(Criteria.where("_id").is(dto.getCommentRepayId()));
            Update update = new Update();
            update.inc("likes",1);
            mongoTemplate.updateFirst(query,update,ApCommentRepay.class);

            // 登陆人操作记录在Redis中，列表展示时进行判断
            // 只需要判断是否存在key即可，set后值可任意
            redisTemplate.boundValueOps("comment_repay_like_" + user.getUserId() + "_" + dto.getCommentRepayId()).set("");


        }else {
            // 取消点赞：1.删除点赞数据 2.修改点赞数
            // 删除点赞数据
            mongoTemplate.remove(new Query(Criteria.where("userId").is(user.getUserId()).and("commentRepayId").is(dto.getCommentRepayId())),ApCommentRepayLike.class);

            // 修改点赞数
            Query query = new Query(Criteria.where("_id").is(dto.getCommentRepayId()));
            Update update = new Update();
            update.inc("likes",-1);
            mongoTemplate.updateFirst(query,update,ApCommentRepay.class);

            // 登陆人操作记录在Redis中，列表展示时进行判断
            // 只需要判断是否存在key即可，set后值可任意
            redisTemplate.delete("comment_repay_like_" + user.getUserId() + "_" + dto.getCommentRepayId());
        }

        return ResponseResult.okResult();
    }

}
